home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / muds / mordor_2.000 / mordor_2 / src / files2.c < prev    next >
C/C++ Source or Header  |  1994-11-29  |  18KB  |  736 lines

  1. /*
  2.  * FILES2.C:
  3.  *
  4.  *    Additional file routines, including memory management.
  5.  *
  6.  *    Copyright (C) 1991, 1992, 1993 Brett J. Vickers
  7.  *
  8.  */
  9.  
  10. #include "mstruct.h"
  11. #include "mextern.h"
  12.  
  13. typedef struct queue_tag {        /* General queue tag data struct */
  14.     int            index;
  15.     struct queue_tag    *next;
  16.     struct queue_tag    *prev;
  17. } qtag;
  18.  
  19. typedef struct rsparse {        /* Sparse pointer array for rooms */
  20.     room             *rom;
  21.     qtag            *q_rom;
  22. } rsparse;
  23.  
  24. typedef struct csparse {        /* Sparse pointer array for creatures */
  25.     creature        *crt;
  26.     qtag            *q_crt;
  27. } csparse;
  28.  
  29. typedef struct osparse {        /* Sparse pointer array for objects */
  30.     object            *obj;
  31.     qtag            *q_obj;
  32. } osparse;
  33.  
  34. static rsparse    Rom[RMAX];    /* Pointer array declared */
  35. static csparse    Crt[CMAX];
  36. static osparse    Obj[OMAX];
  37.  
  38. static qtag    *Romhead=0;    /* Queue header and tail pointers */
  39. static qtag    *Romtail=0;
  40. static qtag    *Crthead=0;
  41. static qtag    *Crttail=0;
  42. static qtag    *Objhead=0;
  43. static qtag    *Objtail=0;
  44.  
  45. int    Rsize=0;        /* Queue sizes */
  46. int    Csize=0;
  47. int    Osize=0;
  48.  
  49. /**********************************************************************/
  50. /*                load_rom                  */
  51. /**********************************************************************/
  52.  
  53. /* This function accepts a room number as its first argument and then   */
  54. /* returns a dblpointer to that room's data in the second parameter.    */
  55. /* If the room has already been loaded, the pointer is simply returned. */
  56. /* Otherwise, the room is loaded into memory.  If a maximal number of   */
  57. /* rooms is already in the memory, then the least recently used room    */
  58. /* is stored back to disk, and the memory is freed.                */
  59.  
  60. int load_rom(index, rom_ptr)
  61. int    index;
  62. room    **rom_ptr;
  63. {
  64.     int    fd;
  65.     qtag    *qt;
  66.     char    file[256], filebak[256];
  67.  
  68.     if(index >= RMAX || index < 0)
  69.         return(-1);
  70.  
  71.     /* Check if room is already loaded, and if so return pointer */
  72.  
  73.     if(Rom[index].rom) {
  74.         front_queue(&Rom[index].q_rom, &Romhead, &Romtail, &Rsize);
  75.         *rom_ptr = Rom[index].rom;
  76.     }
  77.  
  78.     /* Otherwise load the room, store rooms if queue size becomes */
  79.     /* too big, and return a pointer to the newly loaded room     */
  80.  
  81.     else {
  82.         sprintf(file, "%s/r%05d", ROOMPATH, index);
  83.         fd = open(file, O_RDONLY, 0);
  84.         if(fd < 0)
  85.             return(-1);
  86.         *rom_ptr = (room *)malloc(sizeof(room));
  87.         if(!*rom_ptr)
  88.             merror("load_rom", FATAL);
  89.         if(read_rom(fd, *rom_ptr) < 0) {
  90.             close(fd);
  91.             return(-1);
  92.         }
  93.         close(fd);
  94.  
  95.         (*rom_ptr)->rom_num = index;
  96.  
  97.         qt = (qtag *)malloc(sizeof(qtag));
  98.         if(!qt)
  99.             merror("load_rom", FATAL);
  100.         qt->index = index;
  101.         Rom[index].rom = *rom_ptr;
  102.         Rom[index].q_rom = qt;
  103.         put_queue(&qt, &Romhead, &Romtail, &Rsize);
  104.  
  105.         while(Rsize > RQMAX) {
  106.  
  107.             pull_queue(&qt, &Romhead, &Romtail, &Rsize);
  108.             if(Rom[qt->index].rom->first_ply) {
  109.                 put_queue(&qt, &Romhead, &Romtail, &Rsize);
  110.                 continue;
  111.             }
  112.             sprintf(file, "%s/r%05d", ROOMPATH, qt->index);
  113.             sprintf(filebak, "%s~", file);
  114.             rename(file, filebak);
  115.             fd = open(file, O_RDWR | O_CREAT, ACC);
  116.             if(fd < 1)
  117.                 return(-1);
  118.             if(!Rom[qt->index].rom)
  119.                 merror("load_rom", NONFATAL);
  120.             if(write_rom(fd, Rom[qt->index].rom, PERMONLY) < 0) {
  121.                 close(fd);
  122.                 unlink(file);
  123.                 rename(filebak, file);
  124.                 merror("write_rom", NONFATAL);
  125.                 return(-1);
  126.             }
  127.             close(fd);
  128.             unlink(filebak);
  129.             free_rom(Rom[qt->index].rom);
  130.             Rom[qt->index].rom = 0;
  131.             free(qt);
  132.         }
  133.     }
  134.  
  135.     return(0);
  136.  
  137. }
  138.  
  139. int is_rom_loaded(num)
  140. int    num;
  141. {
  142.     return(Rom[num].rom != 0);
  143. }
  144.  
  145. /**********************************************************************/
  146. /*                reload_rom                  */
  147. /**********************************************************************/
  148.  
  149. /* This function reloads a room from disk, if it's already loaded.  This  */
  150. /* allows you to make changes to a room, and then reload it, even if it's */
  151. /* already in the memory room queue.                      */
  152.  
  153. int reload_rom(num)
  154. int    num;
  155. {
  156.     room    *rom_ptr;
  157.     ctag    *cp;
  158.     otag    *op;
  159.     char    file[80];
  160.     int    fd;
  161.  
  162.     if(!Rom[num].rom)
  163.         return(0);
  164.  
  165.     sprintf(file, "%s/r%05d", ROOMPATH, num);
  166.     fd = open(file, O_RDONLY, 0);
  167.     if(fd < 0)
  168.         return(-1);
  169.     rom_ptr = (room *)malloc(sizeof(room));
  170.     if(!rom_ptr)
  171.         merror("reload_rom", FATAL);
  172.     if(read_rom(fd, rom_ptr) < 0) {
  173.         close(fd);
  174.         return(-1);
  175.     }
  176.     close(fd);
  177.  
  178.     rom_ptr->first_ply = Rom[num].rom->first_ply;
  179.     Rom[num].rom->first_ply = 0;
  180.  
  181.     add_permcrt_rom(rom_ptr);
  182.     if(!rom_ptr->first_mon) {
  183.         rom_ptr->first_mon = Rom[num].rom->first_mon;
  184.         Rom[num].rom->first_mon = 0;
  185.     }
  186.  
  187.     if(!rom_ptr->first_obj) {
  188.         rom_ptr->first_obj = Rom[num].rom->first_obj;
  189.         Rom[num].rom->first_obj = 0;
  190.     }
  191.  
  192.     free_rom(Rom[num].rom);
  193.     Rom[num].rom = rom_ptr;
  194.  
  195.     cp = rom_ptr->first_ply;
  196.     while(cp) {
  197.         cp->crt->parent_rom = rom_ptr;
  198.         cp = cp->next_tag;
  199.     }
  200.  
  201.     cp = rom_ptr->first_mon;
  202.     while(cp) {
  203.         cp->crt->parent_rom = rom_ptr;
  204.         cp = cp->next_tag;
  205.     }
  206.  
  207.     op = rom_ptr->first_obj;
  208.     while(op) {
  209.         op->obj->parent_rom = rom_ptr;
  210.         op = op->next_tag;
  211.     }
  212.  
  213.     return(0);
  214.  
  215. }
  216.  
  217. /**********************************************************************/
  218. /*                resave_rom                  */
  219. /**********************************************************************/
  220.  
  221. /* This function saves an already-loaded room back to memory without */
  222. /* altering its position on the queue.                     */
  223.  
  224. int resave_rom(num)
  225. int    num;
  226. {
  227.     char    file[256], filebak[256];
  228.     int    fd;
  229.  
  230.     if(!Rom[num].rom)
  231.         return(0);
  232.  
  233.     sprintf(file, "%s/r%05d", ROOMPATH, num);
  234.     sprintf(filebak, "%s~", file);
  235.     rename(file, filebak);
  236.     fd = open(file, O_RDWR | O_CREAT, ACC);
  237.     if(fd < 1)
  238.         return(-1);
  239.     if(write_rom(fd, Rom[num].rom, PERMONLY) < 0) {
  240.         close(fd);
  241.         unlink(file);
  242.         rename(filebak, file);
  243.         return(-1);
  244.     }
  245.     close(fd);
  246.     unlink(filebak);
  247.  
  248.     return(0);
  249.  
  250. }
  251.  
  252. /**********************************************************************/
  253. /*                resave_all_rom                  */
  254. /**********************************************************************/
  255.  
  256. /* This function saves all memory-resident rooms back to disk.  If the */
  257. /* permonly parameter is non-zero, then only permanent items in those  */
  258. /* rooms are saved back.                           */
  259.  
  260. void resave_all_rom(permonly)
  261. int    permonly;
  262. {
  263.     qtag     *qt;
  264.     char    file[80];
  265.     int    fd;
  266.  
  267.     qt = Romhead;
  268.     while(qt) {
  269.         if(!Rom[qt->index].rom) {
  270.             qt = qt->next;
  271.             continue;
  272.         }
  273.  
  274.         sprintf(file, "%s/r%05d", ROOMPATH, qt->index);
  275.         fd = open(file, O_RDWR | O_CREAT, ACC);
  276.         if(fd < 1)
  277.             return;
  278.         if(write_rom(fd, Rom[qt->index].rom, permonly) < 0) {
  279.             close(fd);
  280.             return;
  281.         }
  282.         close(fd);
  283.         qt = qt->next;
  284.     }
  285. }
  286.  
  287. /**********************************************************************/
  288. /*                save_all_ply                  */
  289. /**********************************************************************/
  290.  
  291. /* This function saves all players currently in memory.              */
  292.  
  293. void save_all_ply()
  294. {
  295.     int i;
  296.  
  297.     for(i=0; i<Tablesize; i++) {
  298.         if(Ply[i].ply && Ply[i].io && Ply[i].ply->name[0])
  299.             savegame(Ply[i].ply, 0);
  300.     }
  301. }
  302.  
  303. /**********************************************************************/
  304. /*                flush_rom                  */
  305. /**********************************************************************/
  306.  
  307. /* This function flushes out the room queue and clears the room sparse */
  308. /* pointer array, without saving anything to file.  It also clears all */
  309. /* memory used by loaded rooms.  Call this function before leaving the */
  310. /* program.                                   */
  311.  
  312. void flush_rom()
  313. {
  314.     qtag *qt;
  315.  
  316.     while(1) {
  317.         pull_queue(&qt, &Romhead, &Romtail, &Rsize);
  318.         if(!qt) break;
  319.         free_rom(Rom[qt->index].rom);
  320.         Rom[qt->index].rom = 0;
  321.         free(qt);
  322.     }
  323. }
  324.  
  325. /**********************************************************************/
  326. /*                flush_crt                  */
  327. /**********************************************************************/
  328.  
  329. /* This function flushes out the monster queue and clears the monster */
  330. /* sparse pointer array without saving anything to file.  It also     */
  331. /* clears all memory used by loaded creatures.  Call this function    */
  332. /* before leaving the program.                          */
  333.  
  334. void flush_crt()
  335. {
  336.     qtag *qt;
  337.  
  338.     while(1) {
  339.         pull_queue(&qt, &Crthead, &Crttail, &Csize);
  340.         if(!qt) break;
  341.         free_crt(Crt[qt->index].crt);
  342.         Crt[qt->index].crt = 0;
  343.         free(qt);
  344.     }
  345. }
  346.  
  347. /**********************************************************************/
  348. /*                flush_obj                  */
  349. /**********************************************************************/
  350.  
  351. /* This function flushes out the object queue and clears the object */
  352. /* sparse pointer array without saving anything to file.  It also   */
  353. /* clears all memory used by loaded objects.  Call this function    */
  354. /* leaving the program.                            */
  355.  
  356. void flush_obj()
  357. {
  358.     qtag *qt;
  359.  
  360.     while(1) {
  361.         pull_queue(&qt, &Objhead, &Objtail, &Osize);
  362.         if(!qt) break;
  363.         free_obj(Obj[qt->index].obj);
  364.         Obj[qt->index].obj = 0;
  365.         free(qt);
  366.     }
  367. }
  368.  
  369. /**********************************************************************/
  370. /*                load_crt                  */
  371. /**********************************************************************/
  372.  
  373. /* This function returns a pointer to the monster given by the index in */
  374. /* the first parameter.  The pointer is returned in the second.  If the */
  375. /* monster is already in memory, then a pointer is merely returned.     */
  376. /* Otherwise, the monster is loaded into memory and a pointer is re-    */
  377. /* turned.  If there are too many monsters in memory, then the least    */
  378. /* recently used one is freed from memory.                */
  379.  
  380. int load_crt(index, mon_ptr)
  381. int        index;
  382. creature    **mon_ptr;
  383. {
  384.     int    fd;
  385.     long    n;
  386.     qtag    *qt;
  387.     char    file[256];
  388.  
  389.     if(index >= CMAX || index < 0)
  390.         return(-1);
  391.  
  392.     /* Check if monster is already loaded, and if so return pointer */
  393.  
  394.     if(Crt[index].crt) {
  395.         front_queue(&Crt[index].q_crt, &Crthead, &Crttail, &Csize);
  396.         *mon_ptr = (creature *)malloc(sizeof(creature));
  397.         **mon_ptr = *Crt[index].crt;
  398.     }
  399.  
  400.     /* Otherwise load the monster, erase monsters if queue size          */
  401.     /* becomes too big, and return a pointer to the newly loaded monster */
  402.  
  403.     else {
  404.         sprintf(file, "%s/m%02d", MONPATH, index/MFILESIZE);
  405.         fd = open(file, O_RDONLY, 0);
  406.         if(fd < 0) {
  407.             *mon_ptr = 0;
  408.             return(-1);
  409.         }
  410.         *mon_ptr = (creature *)malloc(sizeof(creature));
  411.         if(!*mon_ptr)
  412.             merror("load_crt", FATAL);
  413.         n = lseek(fd, (long)((index%MFILESIZE)*sizeof(creature)), 0);
  414.         if(n < 0L) {
  415.             free(*mon_ptr);
  416.             close(fd);
  417.             *mon_ptr = 0;
  418.             return(-1);
  419.         }
  420.         n = read(fd, *mon_ptr, sizeof(creature));
  421.         close(fd);
  422.         if(n < sizeof(creature)) {
  423.             free(*mon_ptr);
  424.             *mon_ptr = 0;
  425.             return(-1);
  426.         }
  427.  
  428.         (*mon_ptr)->fd = -1;
  429.         qt = (qtag *)malloc(sizeof(qtag));
  430.         if(!qt)
  431.             merror("load_crt", FATAL);
  432.         qt->index = index;
  433.         Crt[index].crt = (creature *)malloc(sizeof(creature));
  434.         *Crt[index].crt = **mon_ptr;
  435.         Crt[index].q_crt = qt;
  436.         put_queue(&qt, &Crthead, &Crttail, &Csize);
  437.  
  438.         while(Csize > CQMAX) {
  439.             pull_queue(&qt, &Crthead, &Crttail, &Csize);
  440.             free_crt(Crt[qt->index].crt);
  441.             Crt[qt->index].crt = 0;
  442.             free(qt);
  443.         }
  444.     }
  445.  
  446.     (*mon_ptr)->lasttime[LT_HEALS].ltime = time(0);
  447.     (*mon_ptr)->lasttime[LT_HEALS].interval = 60L;
  448.     (*mon_ptr)->first_enm= 0;
  449.  
  450.     return(0);
  451.  
  452. }
  453.  
  454. /**********************************************************************/
  455. /*                load_obj                  */
  456. /**********************************************************************/
  457.  
  458. /* This function loads the object specified by the first parameter, and */
  459. /* returns a pointer to it in the second parameter.  If the object has  */
  460. /* already been loaded before, then a pointer is merely returned.       */
  461. /* Otherwise, the object is loaded into memory and the pointer is       */
  462. /* returned.  If there are too many objects in memory, then the least   */
  463. /* recently used objects are freed from memory.                */
  464.  
  465. int load_obj(index, obj_ptr)
  466. int    index;
  467. object    **obj_ptr;
  468. {
  469.     int    fd;
  470.     long    n;
  471.     qtag    *qt;
  472.     char    file[256];
  473.  
  474.     if(index >= OMAX || index < 0)
  475.         return(-1);
  476.  
  477.     /* Check if object is already loaded, and if so return pointer */
  478.  
  479.     if(Obj[index].obj) {
  480.         front_queue(&Obj[index].q_obj, &Objhead, &Objtail, &Osize);
  481.         *obj_ptr = (object *)malloc(sizeof(object));
  482.         **obj_ptr = *Obj[index].obj;
  483.     }
  484.  
  485.     /* Otherwise load the object, erase objects if queue size           */
  486.     /* becomes too big, and return a pointer to the newly loaded object */
  487.  
  488.     else {
  489.         sprintf(file, "%s/o%02d", OBJPATH, index/OFILESIZE);
  490.         fd = open(file, O_RDONLY, 0);
  491.         if(fd < 0)
  492.             return(-1);
  493.         *obj_ptr = (object *)malloc(sizeof(object));
  494.         if(!*obj_ptr)
  495.             merror("load_obj", FATAL);
  496.         n = lseek(fd, (long)((index%OFILESIZE)*sizeof(object)), 0);
  497.         if(n < 0L) {
  498.             close(fd);
  499.             return(-1);
  500.         }
  501.         n = read(fd, *obj_ptr, sizeof(object));
  502.         close(fd);
  503.         if(n < sizeof(object))
  504.             return(-1);
  505.  
  506.         qt = (qtag *)malloc(sizeof(qtag));
  507.         if(!qt)
  508.             merror("load_obj", FATAL);
  509.         qt->index = index;
  510.         Obj[index].obj = (object *)malloc(sizeof(object));
  511.         *Obj[index].obj = **obj_ptr;
  512.         Obj[index].q_obj = qt;
  513.         put_queue(&qt, &Objhead, &Objtail, &Osize);
  514.         while(Osize > OQMAX) {
  515.             pull_queue(&qt, &Objhead, &Objtail, &Osize);
  516.             free_obj(Obj[qt->index].obj);
  517.             Obj[qt->index].obj = 0;
  518.             free(qt);
  519.         }
  520.     }
  521.  
  522.     return(0);
  523.  
  524. }
  525.  
  526. /***********************************************************************/
  527. /*                save_ply                   */
  528. /***********************************************************************/
  529.  
  530. /* This function saves the player specified by the string in the first */
  531. /* parameter, and uses the player in the second parameter.           */
  532.  
  533. int save_ply(str, ply_ptr)
  534. char        *str;
  535. creature    *ply_ptr;
  536. {
  537.     char    file[256], filebak[256];
  538.     int    fd, n;
  539. #ifdef COMPRESS
  540.     char    *a_buf, *b_buf;
  541.     int    size;
  542. #endif
  543.  
  544.     sprintf(file, "%s/%s", PLAYERPATH, str);
  545.     sprintf(filebak, "%s~", file);
  546.     rename(file, filebak);
  547.     fd = open(file, O_RDWR | O_CREAT, ACC);
  548.     if(fd < 0) {
  549.         rename(filebak, file);
  550.         return(-1);
  551.     }
  552.  
  553. #ifdef COMPRESS
  554.     a_buf = (char *)malloc(100000);
  555.     if(!a_buf) merror("Memory allocation", FATAL);
  556.     n = write_crt_to_mem(a_buf, ply_ptr, 0);
  557.     if(n > 100000) merror(ply_ptr->name, FATAL);
  558.     b_buf = (char *)malloc(n);
  559.     if(!b_buf) merror("Memory allocation", FATAL);
  560.     size = compress(a_buf, b_buf, n);
  561.     n = write(fd, b_buf, size);
  562.     free(a_buf);
  563.     free(b_buf);
  564. #else
  565.     n = write_crt(fd, ply_ptr, 0);
  566.     if(n < 0) {
  567.         close(fd);
  568.         unlink(file);
  569.         rename(filebak, file);
  570.         return(-1);
  571.     }
  572. #endif
  573.  
  574.     close(fd);
  575.     unlink(filebak);
  576.     return(0);
  577.  
  578. }
  579.  
  580. /***********************************************************************/
  581. /*                load_ply                   */
  582. /***********************************************************************/
  583.  
  584. /* This function loads the player specified by the string in the first */
  585. /* parameter, and returns the player in the second parameter.           */
  586.  
  587. int load_ply(str, ply_ptr)
  588. char        *str;
  589. creature    **ply_ptr;
  590. {
  591.     char    file[80];
  592.     int    fd, n;
  593. #ifdef COMPRESS
  594.     char    *a_buf, *b_buf;
  595.     int    size;
  596. #endif
  597.  
  598.     sprintf(file, "%s/%s", PLAYERPATH, str);
  599.     fd = open(file, O_RDONLY, 0);
  600.     if(fd < 0) 
  601.         return(-1);
  602.  
  603.     *ply_ptr = (creature *)malloc(sizeof(creature));
  604.     if(!*ply_ptr)
  605.         merror("load_ply", FATAL);
  606.  
  607. #ifdef COMPRESS
  608.     a_buf = (char *)malloc(50000);
  609.     if(!a_buf) merror("Memory allocation", FATAL);
  610.     size = read(fd, a_buf, 50000);
  611.     if(size >= 50000) merror("Player too large", FATAL);
  612.     if(size < 1) {
  613.         close(fd);
  614.         return(-1);
  615.     }
  616.     b_buf = (char *)malloc(100000);
  617.     if(!b_buf) merror("Memory allocation", FATAL);
  618.     n = uncompress(a_buf, b_buf, size);
  619.     if(n > 100000) merror("Player too large", FATAL);
  620.     n = read_crt_from_mem(b_buf, *ply_ptr, 0);
  621.     free(a_buf);
  622.     free(b_buf);
  623. #else
  624.     n = read_crt(fd, *ply_ptr);
  625.     if(n < 0) {
  626.         close(fd);
  627.         return(-1);
  628.     }
  629. #endif
  630.  
  631.     close(fd);
  632.     return(0);
  633.  
  634. }
  635.  
  636. /**********************************************************************/
  637. /*                put_queue                  */
  638. /**********************************************************************/
  639.  
  640. /* put_queue places the queue tag pointed to by the first paramater onto */
  641. /* a queue whose head and tail tag pointers are the second and third     */
  642. /* parameters.  If parameters 2 & 3 are 0, then a new queue is created.  */
  643. /* The fourth parameter points to a queue size counter which is      */
  644. /* incremented.                                     */
  645.  
  646. void put_queue(qt, headptr, tailptr, sizeptr)
  647. qtag    **qt;
  648. qtag    **headptr;
  649. qtag    **tailptr;
  650. int    *sizeptr;
  651. {
  652.     *sizeptr = *sizeptr + 1;
  653.  
  654.     if(!*headptr) {
  655.         *headptr = *qt;
  656.         *tailptr = *qt;
  657.         (*qt)->next = 0;
  658.         (*qt)->prev = 0;
  659.     }
  660.  
  661.     else {
  662.         (*headptr)->prev = *qt;
  663.         (*qt)->next = *headptr;
  664.         (*qt)->prev = 0;
  665.         *headptr = *qt;
  666.     }
  667. }
  668.  
  669. /**********************************************************************/
  670. /*                pull_queue                  */
  671. /**********************************************************************/
  672.  
  673. /* pull_queue removes the last queue tag on the queue specified by the */
  674. /* second and third parameters and returns that tag in the first       */
  675. /* parameter.  The fourth parameter points to a queue size counter     */
  676. /* which is decremented.                           */
  677.  
  678. void pull_queue(qt, headptr, tailptr, sizeptr)
  679. qtag     **qt;
  680. qtag    **headptr;
  681. qtag    **tailptr;
  682. int    *sizeptr;
  683. {
  684.     if(!*tailptr)
  685.         *qt = 0;
  686.     else {
  687.         *sizeptr = *sizeptr - 1;
  688.         *qt = *tailptr;
  689.         if((*qt)->prev) {
  690.             (*qt)->prev->next = 0;
  691.             *tailptr = (*qt)->prev;
  692.         }
  693.         else {
  694.             *headptr = 0;
  695.             *tailptr = 0;
  696.         }
  697.     }
  698. }
  699.  
  700. /**********************************************************************/
  701. /*                front_queue                  */
  702. /**********************************************************************/
  703.  
  704. /* front_queue removes the queue tag pointed to by the first parameter */
  705. /* from the queue (specified by the second and third parameters) and   */
  706. /* places it back at the head of the queue.  The fourth parameter is a */
  707. /* pointer to a queue size counter, and it remains unchanged.          */
  708.  
  709. void front_queue(qt, headptr, tailptr, sizeptr)
  710. qtag    **qt;
  711. qtag    **headptr;
  712. qtag    **tailptr;
  713. int    *sizeptr;
  714. {
  715.     if((*qt)->prev) {
  716.         ((*qt)->prev)->next = (*qt)->next;
  717.         if(*qt == *tailptr)
  718.             *tailptr = (*qt)->prev;
  719.     }
  720.     if((*qt)->next) {
  721.         ((*qt)->next)->prev = (*qt)->prev;
  722.         if(*qt == *headptr)
  723.             *headptr = (*qt)->next;
  724.     }
  725.     if(!(*qt)->prev && !(*qt)->next) {
  726.         *headptr = 0;
  727.         *tailptr = 0;
  728.     }
  729.     (*qt)->next = 0;
  730.     (*qt)->prev = 0;
  731.     *sizeptr = *sizeptr - 1;
  732.  
  733.     put_queue(qt, headptr, tailptr, sizeptr);
  734. }
  735.  
  736.